package owg.util;

import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.KeyEvent;
/**This class may be used to monitor the keyboard state, recording all currently pressed and released keys.
 * For best accuracy, please call {@link #register()} at program start.*/
public class KeyboardState implements AWTEventListener
	{
	public static final int NUM_KEYCODES = 128;
	private static boolean isRegistered = false;

	private static boolean[] keyPresses = new boolean[NUM_KEYCODES];
	
	public static void register()
		{
		if(!isRegistered)
			{
			Toolkit.getDefaultToolkit().addAWTEventListener(new KeyboardState(), AWTEvent.KEY_EVENT_MASK);
			isRegistered = true;
			}
		}
	/**
	 * Get whether the indicated key(e.g. KeyEvent.VK_SPACE) is down.
	 * @param keyCode The virtual key code to check. Must be between 0 and NUM_KEYCODES.
	 * @return Whether the key state is down. This may fail if the user changes the window focus while pressing or releasing keys.
	 * @throws IllegalArgumentException If the key code is out of range.
	 */
	public static boolean isKeyDown(int keyCode) throws IllegalArgumentException
		{
		if(keyCode >= NUM_KEYCODES)
			throw new IllegalArgumentException("Key Code out of range: "+keyCode);
		register();
		return keyPresses[keyCode];
		}


	@Override
	public void eventDispatched(AWTEvent event)
		{
		KeyEvent e = (KeyEvent) event;
		int code = e.getKeyCode();
		if(code >= NUM_KEYCODES)
			return;
		if(e.getID() == KeyEvent.KEY_PRESSED)
			keyPresses[code] = true;
		else if(e.getID() == KeyEvent.KEY_RELEASED)
			keyPresses[code] = false;
		}
	public static int getModifierMask()
		{
		int mask = 0;
		if(keyPresses[KeyEvent.VK_CONTROL])
			mask |= KeyEvent.CTRL_DOWN_MASK;
		if(keyPresses[KeyEvent.VK_ALT])
			mask |= KeyEvent.ALT_DOWN_MASK;
		if(keyPresses[KeyEvent.VK_SHIFT])
			mask |= KeyEvent.SHIFT_DOWN_MASK;
		return mask;
		}
	}
